import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import TreeNode from "./TreeNode";
/**
 * 树
 */
var Tree = /*#__PURE__*/function () {
  function Tree(data, options) {
    var _this = this;
    _classCallCheck(this, Tree);
    _defineProperty(this, "uniqueKey", 'key');
    _defineProperty(this, "childrenKey", 'children');
    _defineProperty(this, "nodes", []);
    if (options !== null && options !== void 0 && options.uniqueKey) this.uniqueKey = options.uniqueKey;
    if (options !== null && options !== void 0 && options.childrenKey) this.childrenKey = options.childrenKey;
    this.nodes = data.map(function (it) {
      return new TreeNode(it, {
        uniqueKey: _this.uniqueKey,
        childrenKey: _this.childrenKey,
        tree: _this
      });
    });
  }

  /** @todo 暂时每次访问均使用新的引用，以使视图更新 */
  _createClass(Tree, [{
    key: "treeData",
    get: function get() {
      return _toConsumableArray(this.nodes);
    }

    /** 遍历 */
  }, {
    key: "forEach",
    value: function forEach(iteratee) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
        mode: 'pre'
      };
      this.nodes.forEach(function (childNode) {
        return childNode.forEach(iteratee, options);
      });
    }

    /** 过滤，仅包含匹配条件的节点 */
  }, {
    key: "filter",
    value: function filter(predicate) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
        mode: 'pre',
        isTree: false
      };
      var result = [];
      this.nodes.forEach(function (childNode) {
        var filtered = childNode.filter(predicate, options);
        result = result.concat(filtered);
      });
      return result;
    }

    /** 遍历转换 */
  }, {
    key: "map",
    value: function map(convert) {
      var result = [];
      this.nodes.forEach(function (childNode) {
        var converted = childNode.map(convert);
        result = result.concat(converted);
      });
      return result;
    }

    /** 转数组 */
  }, {
    key: "toArray",
    value: function toArray() {
      return this.map(function (node) {
        return node;
      });
    }

    /** 转键值对映射 */
  }, {
    key: "toMap",
    value: function toMap() {
      var result = {};
      this.forEach(function (node) {
        result[node.key] = node;
      });
      return result;
    }
  }, {
    key: "length",
    get: function get() {
      return this.toArray().length;
    }

    /** 是否包含 */
  }, {
    key: "has",
    value: function has(predicate) {
      return this.nodes.some(function (childNode) {
        return childNode.has(typeof predicate === 'string' ? function (node) {
          return node.key === predicate;
        } : predicate);
      });
    }

    /** 通过匹配规则查找 */
  }, {
    key: "query",
    value: function query(predicate) {
      var result;
      this.nodes.some(function (childNode) {
        var found = childNode.query(typeof predicate === 'string' ? function (node) {
          return node.key === predicate;
        } : predicate);
        if (found) {
          result = found;
          return true;
        }
      });
      return result;
    }

    /** 获取子孙节点，平铺数组形式 */
  }, {
    key: "getPosterityNodes",
    value: function getPosterityNodes(node) {
      if (node) {
        return node.toArray().filter(function (it) {
          return it.key !== node.key;
        });
      } else {
        return this.toArray();
      }
    }

    /** 获取所有叶子节点 */
  }, {
    key: "getMaybeLeafNodes",
    value: function getMaybeLeafNodes(node) {
      if (node) {
        return node.filter(function (it) {
          return it.isMaybeLeaf;
        });
      } else {
        return this.filter(function (it) {
          return it.isMaybeLeaf;
        });
      }
    }

    /** 尾部添加子节点（不改变原始数据） */
  }, {
    key: "append",
    value: function append(node, data) {
      if (node instanceof TreeNode) {
        if (!data) throw new Error('data muse not be undefined');
        if (this.has(data[this.uniqueKey])) {
          throw new Error("".concat(data[this.uniqueKey], " is existed already"));
        }
        node.append(data);
      } else {
        if (this.has(node[this.uniqueKey])) {
          throw new Error("".concat(node[this.uniqueKey], " is existed already"));
        }
        this.nodes.push(new TreeNode(node, {
          uniqueKey: this.uniqueKey,
          childrenKey: this.childrenKey,
          tree: this
        }));
      }
      return this;
    }

    /** 尾部添加子节点列表（不改变原始数据） */
  }, {
    key: "appendChildren",
    value: function appendChildren(node, datas) {
      var _this2 = this;
      if (node instanceof TreeNode) {
        if (!datas) throw new Error('datas muse not be undefined');
        datas.forEach(function (data) {
          if (_this2.has(data[_this2.uniqueKey])) {
            throw new Error("".concat(data[_this2.uniqueKey], " is existed already"));
          }
        });
        node.appendChildren(datas);
      } else {
        node.forEach(function (data) {
          if (_this2.has(data[_this2.uniqueKey])) {
            throw new Error("".concat(data[_this2.uniqueKey], " is existed already"));
          }
        });
        node.forEach(function (data) {
          var nodeToAppend = new TreeNode(data, {
            uniqueKey: _this2.uniqueKey,
            childrenKey: _this2.childrenKey,
            tree: _this2
          });
          _this2.nodes.push(nodeToAppend);
        });
      }
      return this;
    }

    /** 头部添加子节点（不改变原始数据） */
  }, {
    key: "prepend",
    value: function prepend(node, data) {
      if (node instanceof TreeNode) {
        if (!data) throw new Error('data muse not be undefined');
        if (this.has(data[this.uniqueKey])) {
          throw new Error("".concat(data[this.uniqueKey], " is existed already"));
        }
        node.prepend(data);
      } else {
        if (this.has(node[this.uniqueKey])) {
          throw new Error("".concat(node[this.uniqueKey], " is existed already"));
        }
        this.nodes.unshift(new TreeNode(node, {
          uniqueKey: this.uniqueKey,
          childrenKey: this.childrenKey,
          tree: this
        }));
      }
      return this;
    }

    /** 头部添加子节点列表（不改变原始数据） */
  }, {
    key: "prependChildren",
    value: function prependChildren(node, datas) {
      var _this3 = this;
      if (node instanceof TreeNode) {
        if (!datas) throw new Error('datas muse not be undefined');
        datas.forEach(function (data) {
          if (_this3.has(data[_this3.uniqueKey])) {
            throw new Error("".concat(data[_this3.uniqueKey], " is existed already"));
          }
        });
        if (datas) node.prependChildren(datas);
      } else {
        node.forEach(function (data) {
          if (_this3.has(data[_this3.uniqueKey])) {
            throw new Error("".concat(data[_this3.uniqueKey], " is existed already"));
          }
        });
        node.reverse().forEach(function (data) {
          var nodeToPrepend = new TreeNode(data, {
            uniqueKey: _this3.uniqueKey,
            childrenKey: _this3.childrenKey,
            tree: _this3
          });
          _this3.nodes.unshift(nodeToPrepend);
        });
      }
      return this;
    }

    /** 指定节点前插入节点（不改变原始数据） */
  }, {
    key: "insertBefore",
    value: function insertBefore(node, data) {
      node.before(data);
      return this;
    }

    /** 指定节点后插入节点（不改变原始数据） */
  }, {
    key: "insertAfter",
    value: function insertAfter(node, data) {
      node.after(data);
      return this;
    }

    /** 交换节点，不限制层级（不改变原始数据） */
  }, {
    key: "exchange",
    value: function exchange(aNode, bNode) {
      aNode === null || aNode === void 0 || aNode.replaceWith(bNode === null || bNode === void 0 ? void 0 : bNode.origin);
      bNode === null || bNode === void 0 || bNode.replaceWith(aNode === null || aNode === void 0 ? void 0 : aNode.origin);
      return this;
    }

    /** 删除节点（不改变原始数据） */
  }, {
    key: "remove",
    value: function remove(node) {
      node.remove();
      return this;
    }
  }], [{
    key: "createInstanceFromFlattenData",
    value: /** 基于扁平化的树数据生成树实例 */
    function createInstanceFromFlattenData(items, options) {
      var _ref = options !== null && options !== void 0 ? options : {},
        _ref$uniqueKey = _ref.uniqueKey,
        uniqueKey = _ref$uniqueKey === void 0 ? 'key' : _ref$uniqueKey,
        _ref$parentKey = _ref.parentKey,
        parentKey = _ref$parentKey === void 0 ? 'parentKey' : _ref$parentKey;
      var map = {};
      items.forEach(function (item) {
        map[item[uniqueKey]] = _objectSpread({}, item);
      });
      items.forEach(function (item) {
        if (item[parentKey]) {
          var parent = map[item[parentKey]];
          if (!parent.__children) parent.__children = [];
          parent.__children.push(map[item[uniqueKey]]);
        }
      });
      var firstLevelItems = Object.keys(map).filter(function (key) {
        return !map[key][parentKey];
      }).map(function (key) {
        return map[key];
      });
      return new Tree(firstLevelItems, {
        uniqueKey: uniqueKey,
        childrenKey: '__children'
      });
    }
  }]);
  return Tree;
}();
export { Tree as default };